package com.bskj.kuaifu.nettyService.service;

import java.net.InetSocketAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bskj.kuaifu.nettyService.protobuf.ParseRegistryMap;
import com.bskj.kuaifu.nettyService.protobuf.code.PacketDecoder;
import com.bskj.kuaifu.nettyService.protobuf.code.PacketEncoder;
import com.bskj.kuaifu.nettyService.service.MQLister.UpRailMsgLister;
import com.bskj.kuaifu.nettyService.service.handler.LogicServerHandler;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * Created by Dell on 2016/2/2.
 */
public class LogicServer {
	private static final Logger logger = LoggerFactory.getLogger(LogicServer.class);
	
	public void start() throws Exception{
		startLogicServer(8088);
		startUpRailMQLister();
	}

	public void startLogicServer(int port) throws Exception {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workGroup = new NioEventLoopGroup();

		ServerBootstrap bootstrap = new ServerBootstrap().group(bossGroup, workGroup)
				.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
					protected void initChannel(SocketChannel channel) throws Exception {
						ChannelPipeline pipeline = channel.pipeline();
						pipeline.addLast("MessageDecoder", new PacketDecoder());
						pipeline.addLast("MessageEncoder", new PacketEncoder());
						pipeline.addLast("LogicServerHandler", new LogicServerHandler());
					}
				});

		bindConnectionOptions(bootstrap);

		bootstrap.bind(new InetSocketAddress(port)).addListener(new ChannelFutureListener() {
			public void operationComplete(ChannelFuture future) throws Exception {
				if (future.isSuccess()) {
					ParseRegistryMap.initRegistry();
					logger.info("[LogicServer] Started Successed, waiting for other server connect...");
				} else {
					logger.error("[LogicServer] Started Failed");
				}
			}
		});
	}

	protected static void bindConnectionOptions(ServerBootstrap bootstrap) {
		bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
		bootstrap.childOption(ChannelOption.SO_LINGER, 0);
		bootstrap.childOption(ChannelOption.TCP_NODELAY, true);

		bootstrap.childOption(ChannelOption.SO_REUSEADDR, true); //调试用
		bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); //心跳机制暂时使用TCP选项，之后再自己实现
	}

	public void startUpRailMQLister() throws Exception {
		String QUEUE_NAME = "com.bskj.kuaifu.upRailMsgQueue";
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("localhost");
		factory.setUsername("guest");
		factory.setPassword("guest");
		factory.setPort(5672);
		factory.setVirtualHost("/");
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		channel.queueDeclare(QUEUE_NAME, true, false, false, null);
		channel.basicConsume(QUEUE_NAME, false, new UpRailMsgLister(channel));
	}
}
